package com.ruoyi.common.utils;

import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.config.ExternalInterfaceConfig;
import com.ruoyi.common.core.domain.ResponseEntityInfo;
import com.ruoyi.common.enums.RequestMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.Random;

/**
 * @PackageName: com.ruoyi.framework.web.service
 * @ClassName: RequestService
 * @Description:
 * @Author: czl
 * @Date: 2025/10/30 21:47
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class RequestService {

    private final RestTemplate restTemplate;
    private final ExternalInterfaceConfig externalInterfaceConfig;

    /**
     * 请求地址
     **/
    public String requestUrl(RequestMapper requestMapper) {
        // 空值检查
        if (externalInterfaceConfig == null) {
            throw new IllegalStateException("External interface config is not initialized");
        }

        String baseUrl = externalInterfaceConfig.getRequestUrl();
        String appId = externalInterfaceConfig.getAppId();
        String appKey = externalInterfaceConfig.getAppKey();

        // 配置项空值检查
        if (baseUrl == null || appId == null || appKey == null) {
            throw new IllegalStateException("Required configuration parameters are missing");
        }

        // 获取当前时间戳（秒）
        long time = System.currentTimeMillis() / 1000;

        // 只生成一次随机字符串，确保签名一致性
        String randomString = generateRandomString();

        try {
            return UriComponentsBuilder.fromHttpUrl(baseUrl + requestMapper.getMapping())
                    .queryParam("app_id", appId)
                    .queryParam("time", time)
                    .queryParam("random", randomString)
                    .queryParam("sign", generateSign(appKey, time, randomString))
                    .toUriString();
        } catch (Exception e) {
            throw new RuntimeException("Failed to build request URL", e);
        }

    }

    /**
     * 生成随机字符串
     **/
    private String generateRandomString() {
        Random random = new Random();
        return String.valueOf(random.nextInt(1000000));
    }

    /**
     * 生成MD5签名
     * 参数sign字段根据公式md5(app_key=$app_key&time=$time&random=$random)生成, 32位不区分大小写
     **/
    private String generateSign(String appKey, long time, String random) {
        String data = String.format("app_key=%s&time=%s&random=%s", appKey, time, random);

        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] messageDigest = md.digest(data.getBytes());
            StringBuilder hexString = new StringBuilder();

            for (byte b : messageDigest) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) {
                    hexString.append('0');
                }
                hexString.append(hex);
            }

            return hexString.toString().toLowerCase();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("MD5 algorithm not available", e);
        }
    }

    /**
     * 高级请求
     **/
    public ResponseEntityInfo advancedRequest(RequestMapper requestMapper, Map<String, Object> params) {
        // 设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        // 构建表单数据
        MultiValueMap<String, Object> formParams = new LinkedMultiValueMap<>();
        if (params != null) {
            formParams.setAll(params);
        }
        log.info("请求参数：{}", params);

        // 创建请求实体
        HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(formParams, headers);
        log.info("请求地址：{}", requestUrl(requestMapper));

        try {
            ResponseEntity<String> exchange = restTemplate.exchange(requestUrl(requestMapper), HttpMethod.POST, request, String.class);
            log.info("请求响应状态码：{}", exchange.getStatusCode());

            if (exchange.getStatusCode().is2xxSuccessful()) {
                String body = exchange.getBody();
                if (body != null) {
                    // 解析为JSONObject以便后续处理
                    com.alibaba.fastjson2.JSONObject jsonObject = JSON.parseObject(body);
                    ResponseEntityInfo responseEntity = new ResponseEntityInfo();
                    responseEntity.setErrno(jsonObject.getIntValue("errno"));
                    responseEntity.setErrmsg(jsonObject.getString("errmsg"));
                    responseEntity.setData(jsonObject.get("data"));
                    if (0 != jsonObject.getIntValue("errno")){
                        log.error("请求失败，错误码：{}，错误信息：{}", jsonObject.getIntValue("errno"), jsonObject.getString("errmsg"));
                    }
                    return responseEntity;
                } else {
                    log.warn("响应体为空");
                    return null;
                }
            } else {
                log.error("请求失败，状态码：{}", exchange.getStatusCode());
                return null;
            }
        } catch (Exception e) {
            log.error("请求发生异常，请求地址：{}", requestUrl(requestMapper), e);
            return null;
        }
    }
}
